﻿using System.Diagnostics;

namespace HK.Core.Utils
{
    /// <summary>
    /// 工具类 : Caller
    /// </summary>
    public static class UtilsCaller
    {

        /// <summary>
        /// 收集调用者信息标志位
        /// <para>* 默认收集(即:false)</para>
        /// </summary>
#if CALLER_COLLECT
        private static bool _collectCaller = true;
#else
        private static bool _collectCaller = false;
#endif
        
        /// <summary>
        /// 取得调用者
        /// <para>* 格式：[调用文件]:[调用类名]:[调用方法名]([行号],[列号])</para>
        /// </summary>
        /// <param name="iSkipFrames">堆栈中跳过的帧数</param>
        /// <returns>调用者详细信息</returns>
        public static string GetCaller(int iSkipFrames = 1)
        {
            if (!_collectCaller) return null;
            
            var stackFrame = new StackFrame(iSkipFrames, false);
            var caller = stackFrame?.GetMethod();
            if (null == caller)
            {
                return string.Empty;
            }

            var callerTxt = string.Empty;
            var fileName = stackFrame.GetFileName();
            if (!string.IsNullOrEmpty(callerTxt))
            {
                callerTxt = fileName;
            }
            var className = caller.DeclaringType?.FullName ?? "Unknown";
            callerTxt = string.IsNullOrEmpty(callerTxt) ? className : $"{callerTxt}:{className}";
            
            var methodName = caller.Name;
            callerTxt = string.IsNullOrEmpty(callerTxt) ? methodName : $"{callerTxt}:{methodName}()";
            
            var lineRowNo = stackFrame.GetFileLineNumber();
            var lineColNo = stackFrame.GetFileColumnNumber();
            if (!string.IsNullOrEmpty(fileName) && 0 < lineRowNo && 0 < lineColNo)
            {
                callerTxt = $"{callerTxt}({lineRowNo}, {lineColNo})";
            }
            return callerTxt;
        }
    }
}
